接下來的實作大多會是以創建 serializer -> 創建 view -> 增加 url 的流程進行,今天預計會把驗證功能做完,開始嘍。
DRF 本身就包含製作驗證功能需要的套件,而此套件在幾天前已經裝在settings.py
中了(rest_framework.authtoken)。到 user/serializer.py 中加入:
# 新增的 import
from django.contrib.auth import get_user_model, authenticate
from django.utils.translation import gettext as _
# ...
class AuthTokenSerializer(serializers.Serializer):
"""Serializer for the user auth token."""
email = serializers.EmailField()
password = serializers.CharField(
style={'input_type': 'password'},
trim_whitespace=False,
)
def validate(self, attrs):
"""Validate and authenticat the user."""
email = attrs.get('email')
password = attrs.get('password')
user = authenticate(
username=email,
password=password,
)
if not user:
msg = _('Unable to authenticate with provided credentials.')
raise serializers.ValidationError(msg, code='authorization')
attrs['user'] = user
return attrs
新導入的是一個驗證方法(authenticate)以及翻譯方法(gettext),而新增的 class 因為沒有特定的 model 可以指定,所以是繼承自serializers.Serializer
,是最基本的序列 class,所以需要自行指定要處理的欄位資料型態,看起來就像定義一個新 model。而密碼部分因為 Django 預設會修掉末端的空白,但有些人可能是故意留空白,所以將此功能關閉。接著定義驗證函式,athenticate 若條件都符合會返回 user 物件,有一項未符合就會回傳 None,因此若驗證失敗會跳錯誤訊息。
再來到 user/views.py 中增加:
# 新導入
from rest_framework.settings import api_settings
from rest_framework.authtoken.views import ObtainAuthToken
from user.serializers import UserSerializer, AuthTokenSerializer
# ...
class CreateTokenView(ObtainAuthToken):
"""Create a new auth token."""
serializer_class = AuthTokenSerializer
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
這邊導入 DRF 的 api_settings 並使用其中預設的DEFAULT_RENDERER_CLASSES
處理回應的格式。再來繼承 rest_framework.authtoken 中的ObtainAuthToken
創建新的 token class。
最後進入 user/urls.py 中,加入 path:
urlpatterns = [
# ...
path('token/', views.CreateTokenView.as_view(), name='token'),
]
儲存後便可以啟動伺服器測試了!首先創建一個使用者,再將使用者的 email 及密碼傳入 api/user/token 中,應該就會獲得一組亂數的 token 了。
完成授權功能後,接下來會新增一些需要授權才能操作的端點。明天見~